package com.ficus.road.maintain.service;

import com.alibaba.fastjson.JSONObject;
import com.ficus.road.maintain.core.dto.weather.WeatherDTO;
import com.ficus.road.maintain.core.dto.weather.WeatherSearchResponse;
import com.ficus.road.maintain.dao.WeatherMongoDao;
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author nan.li
 * @date 2020.09.21
 */
@Slf4j
@Service
@EnableScheduling
public class WeatherSearchService {
    private RestTemplate restTemplate;
    private SimpleDateFormat hourDateFormat;
    private SimpleDateFormat DateFormat;
    @Autowired
    private WeatherMongoDao weatherMongoDao;
    @Value("${weather.province}")
    private String province;
    @Value("${weather.city}")
    private String city;
    @Value("${weather.county}")
    private String county;


    @PostConstruct
    private void init() {
        restTemplate = new RestTemplate();
        hourDateFormat = new SimpleDateFormat("yyyyMMddHH0000");
        DateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        this.storageWeather();
    }

    @Scheduled(cron = "${cron-config.weather}")
    private void cronGetWeather() {
        this.storageWeather();
    }


    private void storageWeather() {
        String weatherUrl = "https://wis.qq.com/weather/common?source={source}&province={province}&city={city}&county={county}&weather_type={weather_type}";
        Map<String, Object> params = new HashMap<>();
        params.put("source", "pc");
        params.put("province", province);
        params.put("city", city);
        params.put("county", county);
        params.put("weather_type", "forecast_1h|air|alarm");
        ResponseEntity<String> exchange = null;
        try {
            exchange = restTemplate.exchange(weatherUrl, HttpMethod.GET, null, String.class, params);
        } catch (Exception ignored) {
            return;
        }
        if (exchange.getStatusCode() == HttpStatus.OK) {
            JSONObject jsonObject = JSONObject.parseObject(exchange.getBody());
            JSONObject jsonData = jsonObject.getJSONObject("data");
            String aqiName = jsonData.getJSONObject("air").getString("aqi_name");
            String aqi = jsonData.getJSONObject("air").getString("aqi");
            JSONObject alarm = jsonData.getJSONObject("alarm");
            String typeName = alarm.isEmpty() ? "" : alarm.getJSONObject("0").getString("type_name");
            String levelName = alarm.isEmpty() ? "" : alarm.getJSONObject("0").getString("level_name");
            LocalDateTime now = LocalDateTime.now();
            jsonData.getJSONObject("forecast_1h").forEach((k, v) -> {
                JSONObject value = (JSONObject) v;
                String updateTime = value.getString("update_time");
                value.put("aqi_name", aqiName);
                value.put("aqi", aqi);
                value.put("alarm_type", typeName);
                value.put("alarm_level", levelName);
                WeatherDTO weatherDTO = new WeatherDTO();
                weatherDTO.setId(updateTime);
                weatherDTO.setCreationTime(now);
                weatherDTO.setWeather(value);
                weatherMongoDao.saveOrUpdate(weatherDTO);
            });
        }
    }

    public WeatherSearchResponse getWeatherInfo(long time) {
        Date date = new Date(time * 1000);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        String format = hourDateFormat.format(cal.getTime());
        log.info("Weather: date: {}", date);
        log.info("Weather: format: {}", format);
        JSONObject fetch = null;
        try {
            fetch = weatherMongoDao.fetch(format).getWeather();
        } catch (Exception ignored) {
            return null;
        }
        WeatherSearchResponse weatherSearchResponse = new WeatherSearchResponse();
        String aqiName = fetch.getString("aqi_name");
        String weather = fetch.getString("weather");
        String degree = fetch.getString("degree");
        String weatherCode = fetch.getString("weather_code");
        String windDirection = fetch.getString("wind_direction");
        String windPower = fetch.getString("wind_power");
        String aqi = fetch.getString("aqi");
        String alarmType = fetch.getString("alarm_type");
        String alarmLevel = fetch.getString("alarm_level");


        Preconditions.checkNotNull(aqiName);
        Preconditions.checkNotNull(weather);
        Preconditions.checkNotNull(degree);
        weatherSearchResponse.setAqiName(aqiName);
        weatherSearchResponse.setDegree(degree);
        weatherSearchResponse.setWeather(weather);
        weatherSearchResponse.setWeatherCode(weatherCode);
        weatherSearchResponse.setAlarmLevel(alarmLevel);
        weatherSearchResponse.setAlarmType(alarmType);
        weatherSearchResponse.setWindDirection(windDirection);
        weatherSearchResponse.setWindPower(windPower);
        weatherSearchResponse.setAqi(aqi);
        return weatherSearchResponse;
    }

}
